package com.fanxuankai.boot.log.autoconfigure;

import com.fanxuankai.boot.log.enums.SafetyLevel;
import com.fanxuankai.boot.log.enums.StoreType;
import org.springframework.beans.BeansException;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * 配置
 *
 * @author fanxuankai
 */
@ConfigurationProperties(prefix = LogProperties.PREFIX)
public class LogProperties implements ApplicationContextAware {
    public static final String PREFIX = "fxk.log";
    public static final String STORE_TYPE = PREFIX + ".store-type";
    public static final String EXPRESSIONS = PREFIX + ".expressions";
    public static final String ASYNC = PREFIX + ".async";
    public static final String ENABLED = PREFIX + ".enabled";
    /**
     * 是否开启 Log
     */
    private boolean enabled = true;
    /**
     * 切入点表达式
     */
    private String expressions;
    /**
     * 存储方式
     */
    private StoreType storeType;
    /**
     * Jdbc 存储配置
     */
    private JdbcStore jdbcStore;
    /**
     * 应用名
     */
    private String application;
    /**
     * 全局配置, 未使用注解的情况下走全局配置
     */
    private GlobalConfig globalConfig = new GlobalConfig();
    /**
     * 异步记录
     */
    private boolean async;
    /**
     * 不转 JSON 的类的接口或者父类
     */
    private Set<String> excludeClassesToJson = Collections.emptySet();

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getExpressions() {
        return expressions;
    }

    public void setExpressions(String expressions) {
        this.expressions = expressions;
    }

    public StoreType getStoreType() {
        return storeType;
    }

    public void setStoreType(StoreType storeType) {
        this.storeType = storeType;
    }

    public JdbcStore getJdbcStore() {
        return jdbcStore;
    }

    public void setJdbcStore(JdbcStore jdbcStore) {
        this.jdbcStore = jdbcStore;
    }

    public String getApplication() {
        return application;
    }

    public void setApplication(String application) {
        this.application = application;
    }

    public GlobalConfig getGlobalConfig() {
        return globalConfig;
    }

    public void setGlobalConfig(GlobalConfig globalConfig) {
        this.globalConfig = globalConfig;
    }

    public boolean isAsync() {
        return async;
    }

    public void setAsync(boolean async) {
        this.async = async;
    }

    public Set<String> getExcludeClassesToJson() {
        return excludeClassesToJson;
    }

    public void setExcludeClassesToJson(Set<String> excludeClassesToJson) {
        this.excludeClassesToJson = excludeClassesToJson;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        setApplication(applicationContext.getEnvironment().getProperty("spring.application.name"));
    }

    public static class JdbcStore {
        /**
         * 表名
         */
        private String tableName;
        /**
         * 自定义字段
         */
        private List<String> customColumns;
        /**
         * 表名根据创建时间切分，例如：format 指定为 yyyy_MM，则表名最终为：sys_log_2022_07
         */
        private String shardingDateFormat;

        public List<String> getCustomColumns() {
            return customColumns;
        }

        public void setCustomColumns(List<String> customColumns) {
            this.customColumns = customColumns;
        }

        public String getTableName() {
            return tableName;
        }

        public void setTableName(String tableName) {
            this.tableName = tableName;
        }

        public String getShardingDateFormat() {
            return shardingDateFormat;
        }

        public void setShardingDateFormat(String shardingDateFormat) {
            this.shardingDateFormat = shardingDateFormat;
        }
    }

    /**
     * 全局配置
     */
    public static class GlobalConfig {
        /**
         * 安全等级, 指该资源的安全等级
         */
        private SafetyLevel safetyLevel = SafetyLevel.NORMAL;
        /**
         * 记录参数
         */
        private boolean params = true;
        /**
         * 记录返回值
         */
        private boolean returnValue = true;
        /**
         * 记录用户信息
         */
        private boolean user = true;

        public SafetyLevel getSafetyLevel() {
            return safetyLevel;
        }

        public void setSafetyLevel(SafetyLevel safetyLevel) {
            this.safetyLevel = safetyLevel;
        }

        public boolean isParams() {
            return params;
        }

        public void setParams(boolean params) {
            this.params = params;
        }

        public boolean isReturnValue() {
            return returnValue;
        }

        public void setReturnValue(boolean returnValue) {
            this.returnValue = returnValue;
        }

        public boolean isUser() {
            return user;
        }

        public void setUser(boolean user) {
            this.user = user;
        }
    }
}